import vad
import wave
import pyaudio
import struct

# 配置
RATE = 16000  # 采样率
FRAME_DURATION = 30  # 帧持续时间（毫秒）
FRAME_SIZE = int(RATE * FRAME_DURATION / 1000)  # 每帧的样本数
CHANNELS = 1  # 单声道

def read_wave(path):
    """读取 wav 文件并返回采样率和音频数据"""
    with wave.open(path, 'rb') as wf:
        num_channels = wf.getnchannels()
        assert num_channels == CHANNELS, f"Expected {CHANNELS} channels, but got {num_channels}"
        sample_width = wf.getsampwidth()
        assert sample_width == 2, f"Expected 16-bit PCM, but got {sample_width * 8}-bit"
        sample_rate = wf.getframerate()
        assert sample_rate == RATE, f"Expected sample rate {RATE}, but got {sample_rate}"
        pcm_data = wf.readframes(wf.getnframes())
    return pcm_data

def main():
    # 创建和初始化VAD实例
    vad_instance = vad.create()
    vad.init(vad_instance)

    # 设置VAD模式
    vad.set_mode(vad_instance, 3)

    # 打开音频流
    p = pyaudio.PyAudio()
    stream = p.open(format=pyaudio.paInt16,
                    channels=CHANNELS,
                    rate=RATE,
                    input=True,
                    frames_per_buffer=FRAME_SIZE)

    print("Listening...")
    try:
        while True:
            frame = stream.read(FRAME_SIZE)
            frame = struct.unpack(f'{FRAME_SIZE}h', frame)  # 将字节数据解包成int16格式
            frame = struct.pack(f'{FRAME_SIZE}h', *frame)   # 将int16数据重新打包成字节数据
            is_speech = vad.process(vad_instance, RATE, frame)
            if is_speech:
                print("Speech detected")
            else:
                print("Silence detected")
    except KeyboardInterrupt:
        print("Stopped")
    finally:
        stream.stop_stream()
        stream.close()
        p.terminate()

if __name__ == "__main__":
    main()